package com.autumn.mybatis.criterion;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.autumn.mybatis.criterion.clauses.SpecifyUpdateClause;
import com.autumn.mybatis.criterion.expressions.ColumnExpression;
import com.autumn.mybatis.criterion.impl.SpecifyUpdateSectionImpl;
import com.autumn.mybatis.metadata.EntityTable;
import com.autumn.util.ExceptionUtils;

/**
 * 指定更新
 * 
 * @author 老码农
 *
 *         2017-10-30 18:37:10
 */
public class SpecifyUpdate extends AbstractCriteria<SpecifyUpdate> {

	/**
	 * 
	 */
	private static final long serialVersionUID = 335632452710064820L;

	/**
	 * 获取排序集合
	 * 
	 * @return
	 */
	private final List<SpecifyUpdateClause> updateClauses = new ArrayList<>();

	/**
	 * 无表实例化
	 */
	public SpecifyUpdate() {

	}

	/**
	 * 转入 entityClass 实例化
	 * 
	 * @param entityClass
	 *            实体类型
	 */
	public SpecifyUpdate(Class<?> entityClass) {
		super(entityClass);
	}

	/**
	 * 转入 EntityTable 实例化
	 * 
	 * @param entityTable
	 *            实体表
	 */
	public SpecifyUpdate(EntityTable entityTable) {
		super(entityTable);
	}

	/**
	 * 重置
	 */
	@Override
	public void reset() {
		super.reset();
		this.updateClauses.clear();
	}

	/**
	 * 
	 * @param columnName
	 */
	private void removeClause(String columnName) {
		Iterator<SpecifyUpdateClause> it = updateClauses.iterator();
		while (it.hasNext()) {
			SpecifyUpdateClause clause = it.next();
			if (columnName.equalsIgnoreCase(clause.getColumnName())) {
				updateClauses.remove(clause);
				break;
			}
		}
	}

	/**
	 * 设置更新
	 * 
	 * @param name
	 *            属性或列名称
	 * @param value
	 *            值
	 * @return
	 */
	public SpecifyUpdate set(String name, Object value) {
		ColumnExpression exp = this.column(name);
		value = this.constantValue(exp, value);
		removeClause(exp.getColumnName());
		this.updateClauses.add(new SpecifyUpdateClause(exp.getColumnName(), value));
		return this;
	}

	/**
	 * 生成
	 * 
	 * @return
	 */
	@Override
	public ISpecifyUpdateSection builderSection() {
		SpecifyUpdateSectionImpl qs = new SpecifyUpdateSectionImpl(this.lockMode);
		// 条件表达式
		qs.getCriterias().addAll(this.createCriteriaSections());
		if (updateClauses.size() == 0) {
			ExceptionUtils.throwApplicationException("至少需要更新一列以上。");
		}
		qs.getUpdateClauses().addAll(this.updateClauses);
		return qs;
	}

}
